﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using BrightIdeasSoftware;
using System.IO;
using System.Xml;
using System.Collections;
using Thanhlichtek.BEF.Fix;
using System.Configuration;

namespace Thanhlichtek.BEF.Win
{

    public partial class MainForm : Form
    {
        private List<FixInfoObject> _fixInfoObjects = new List<FixInfoObject>();
        private String _profileFolder = "Profile";
        FixManager fixManager;

        Thread fixThread;

        public MainForm()
        {
            InitializeComponent();
        }

        private void tsbStartSync_Click(object sender, EventArgs e)
        {
            try
            {
                if (tsbStartFix.Text == "Stop fixing emails")
                {
                    try
                    {
                        fixManager.StopSyncList();
                        fixThread.Abort();
                    }
                    catch (Exception)
                    {
                        
                        //throw;
                    }
                    tsbStartFix.Text = "Start fixing emails";
                    tsbStartFix.Image = Properties.Resources.start;
                    return;
                }
                _fixInfoObjects.Clear();
                objectListView1.SetObjects(_fixInfoObjects);
                objectListView1.BuildList();

                fixManager = new FixManager();

                fixManager.FixStart += new EventHandler(fixManager_FixStart);
                fixManager.SyncStop += new EventHandler(fixManager_FixStop);
                fixManager.ConnectingStart += new EventHandler(fixManager_ConnectingStart);
                fixManager.GettingBullhornListsStart += new EventHandler(fixManager_GettingBullhornListsStart);
                fixManager.GettingBullhornListsStop += new EventHandler(fixManager_GettingBullhornListsStop);
                fixManager.FixListStart += new EventHandler(fixManager_FixListStart);
                fixManager.FixListStop += new EventHandler(fixManager_FixListStop);
                fixManager.GetClientContactIdsStart += new EventHandler(fixManager_GetClientContactIdsStart);
                fixManager.GetClientContactIdsStop += new EventHandler(fixManager_GetClientContacsOfListStop);

                fixManager.FixContactSuccess += new EventHandler(fixManager_UpdateListInfo);
                fixManager.FixContactFail += new EventHandler(fixManager_UpdateListInfo);
                fixManager.FixContactIgnore += new EventHandler(fixManager_UpdateListInfo);

                fixManager.FixContactsStart += new EventHandler(fixManager_FixContactsStart);
                fixManager.FixError += new EventHandler(fixManager_FixError);
                fixManager.GettingBullhornListInfoStart += new EventHandler(fixManager_GettingBullhornListInfoStart);

                fixThread = new Thread(new ThreadStart(fixManager.StartFixing));
                fixThread.IsBackground = true;
                fixThread.Start();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace);
            }

            
        }

        void fixManager_GettingBullhornListInfoStart(object sender, EventArgs e)
        {
            SetLabelStatus(((FixEventArgs)e).Message);
        }

        void fixManager_FixError(object sender, EventArgs e)
        {
            this.Invoke(() => {
                MessageBox.Show(((FixEventArgs)e).Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                var foundItem = _fixInfoObjects.Find(x => x.Status == "Processing");
                if (foundItem != null)
                {
                    foundItem.Status = "Failed";
                    objectListView1.RefreshObject(foundItem);
                }
                
            });
        }

        void fixManager_UpdateListInfo(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                var e2 = (FixEventArgs)e;
                FixManager syncManager = (FixManager)sender;
                var distributionList = e2.BullhornListInfoObj.DistributionList;
                var bullhornAccount = e2.BullhornListInfoObj.BullhornAccountFixInfoObj.BullhornAccount;
                var foundItem = _fixInfoObjects.Find(x => x.BullhornListId == distributionList.distributionListID && x.BullhornAccount.Id == bullhornAccount.Id);

                //counting
                var queryFailed = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                                  where x.State == FixState.Failed
                                  select x;
                foundItem.NoOfFailed = queryFailed.ToList().Count;

                var queryFixed = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                                   where x.State == FixState.Fixed
                                   select x;
                foundItem.NoOfFixedClientContacts = queryFixed.ToList().Count;

                var queryIgnored = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                                   where x.State == FixState.Ignored
                                   select x;
                foundItem.NoOfIgnored = queryIgnored.ToList().Count;
                //end counting

                foundItem.Progress = String.Format("{0}/{1}",
                    foundItem.NoOfFailed + foundItem.NoOfFixedClientContacts + foundItem.NoOfIgnored,
                    e2.BullhornListInfoObj.ClientContactInfoDict.Count);

                objectListView1.RefreshObject(foundItem);

                foundItem.FixInfoDetailObjects.Clear();
                foreach (var item in e2.BullhornListInfoObj.ClientContactInfoDict.Values)
                {
                    if (item.State == FixState.NotFixed || item.State == FixState.Fixing)
                    {
                        continue;
                    }
                    var fixInfoDetailObject = new FixInfoDetailObject();
                    fixInfoDetailObject.FixInfoObject = foundItem;
                    fixInfoDetailObject.ClientContact = item.ClientContact;
                    fixInfoDetailObject.Status = item.Message;
                    fixInfoDetailObject.FixedEmail = item.FixedEmail;
                    foundItem.FixInfoDetailObjects.Add(fixInfoDetailObject);
                }


            });
        }


        void fixManager_FixContactsStart(object sender, EventArgs e)
        {
            SetLabelStatus(((FixEventArgs)e).Message);
        }

        void fixManager_GetClientContacsOfListStop(object sender, EventArgs e)
        {
            this.Invoke(() => {
                var e2 = (FixEventArgs)e;
                var contactInfos = e2.BullhornListInfoObj.ClientContactInfoDict.Values;
                var bullhornAccount = e2.BullhornListInfoObj.BullhornAccountFixInfoObj.BullhornAccount;
                var distributionList = e2.BullhornListInfoObj.DistributionList;
                var foundItem = _fixInfoObjects.Find(x => x.BullhornListId == distributionList.distributionListID && x.BullhornAccount.Id == bullhornAccount.Id);
                if (contactInfos == null)
                {
                    foundItem.NoOfClientContacts = 0;
                }
                else
                {
                    foundItem.NoOfClientContacts = contactInfos.Count();
                }
                objectListView1.RefreshObject(foundItem);
                
            });
        }

        void fixManager_GetClientContactIdsStart(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                var e2 = (FixEventArgs)e;
                SetLabelStatus(((FixEventArgs)e).Message);
            });
            
        }

       

        void fixManager_FixStop(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                tsbStartFix.Text = "Start fixing email";
                tsbStartFix.Image = Properties.Resources.start;
                lblStatus.Text = ((FixEventArgs)e).Message;

                //Generate reports
                List<ContactListItem> contactItems = new List<ContactListItem>();
                //Distribution List Statistics
                foreach (var syncInfoObject in _fixInfoObjects)
                {
                    var salesPerson = syncInfoObject.SalesPerson;
                    //DistributionListStatisticsItem statsItem;
                    var details = syncInfoObject.FixInfoDetailObjects;
                    var notNullDetails = details.FindAll(x => x.ClientContact != null && !String.IsNullOrEmpty(x.FixedEmail));

                    //contact item
                    foreach (var detail in notNullDetails)
                    {
                        var contactItem = new ContactListItem();
                        if (detail.ClientContact == null)
                        {
                            continue;
                        }
                        contactItem.FirstName = detail.FirstName;
                        contactItem.LastName = detail.LastName;
                        contactItem.Email = detail.Email;
                        contactItem.FixedEmail = detail.FixedEmail;
                        contactItem.DistributionListName = syncInfoObject.BullhornListName;
                        contactItems.Add(contactItem);
                    }
                }
                //add data
                int row = 2;

                //ContactListReport
                var excell_app2 = new ExcelHelper();
                //creates subheaders
                excell_app2.createHeaders(1, 1, "Contact First Name");
                excell_app2.createHeaders(1, 2, "Contact Last Name");
                excell_app2.createHeaders(1, 3, "Contact Email");
                excell_app2.createHeaders(1, 4, "Fixed Email");
                excell_app2.createHeaders(1, 5, "Distribution List Name");
                //add data
                row = 2;
                foreach (var contactItem in contactItems)
                {
                    excell_app2.addData(row, 1, contactItem.FirstName);
                    excell_app2.addData(row, 2, contactItem.LastName);
                    excell_app2.addData(row, 3, contactItem.Email);
                    excell_app2.addData(row, 4, contactItem.FixedEmail);
                    excell_app2.addData(row, 5, contactItem.DistributionListName);

                    row++;
                }

                excell_app2.save("CorrectedEmailsOn");

            });
        }

        void fixManager_FixStart(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                //tsbStartSync.Enabled = false;
                tsbStartFix.Text = "Stop fixing emails";
                tsbStartFix.Image = Properties.Resources.stop;
            });
        }

        void fixManager_FixListStop(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                var e2 = (FixEventArgs)e;
                var bullhornAccount = e2.BullhornListInfoObj.BullhornAccountFixInfoObj.BullhornAccount;
                var distributionList = e2.BullhornListInfoObj.DistributionList;
                var foundItem = _fixInfoObjects.Find(x => x.BullhornListId == distributionList.distributionListID && x.BullhornAccount.Id == bullhornAccount.Id);

                //counting
                //var queryFailed = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                //                  where x.State == FixState.Failed
                //                  select x;
                //foundItem.NoOfFailed = queryFailed.ToList().Count;

                //var queryFixed = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                //                   where x.State == FixState.Fixed
                //                   select x;
                //foundItem.NoOfFixedClientContacts = queryFixed.ToList().Count;

                //var queryIgnored = from x in e2.BullhornListInfoObj.ClientContactInfoDict.Values
                //                   where x.State == FixState.Ignored
                //                   select x;
                //foundItem.NoOfIgnored = queryIgnored.ToList().Count;
                //end counting


                foundItem.Status = "Completed";
                objectListView1.RefreshObject(foundItem);

            });
        }

        void fixManager_FixListStart(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                var e2 = (FixEventArgs)e;
                var distributionList = e2.BullhornListInfoObj.DistributionList;
                var foundItem = _fixInfoObjects.Find(x => x.BullhornListId == distributionList.distributionListID && x.BullhornAccount.Id == e2.BullhornListInfoObj.BullhornAccountFixInfoObj.BullhornAccount.Id);
                foundItem.Status = "Processing";
                objectListView1.RefreshObject(foundItem);
                objectListView1.SelectObject(foundItem, true);
            });
        }

        void fixManager_GettingBullhornListsStop(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                var e2 = (FixEventArgs)e;
                var lists = e2.BullhornAccountFixInfoObj.BullhornListInfoDict.Values;
                foreach (var bullhornListInfoItem in lists)
                {
                    var fixInfoObject = new FixInfoObject();
                    fixInfoObject.BullhornAccount = e2.BullhornAccountFixInfoObj.BullhornAccount;
                    fixInfoObject.BullhornList = bullhornListInfoItem.DistributionList;
                    fixInfoObject.CorporateUser = bullhornListInfoItem.CorporateUser;
                    fixInfoObject.Status = "Pending";

                    _fixInfoObjects.Add(fixInfoObject);
                    objectListView1.BuildList(true);
                }

            });
        }

        void SetLabelStatus(String message)
        {
            this.Invoke(() => {
                lblStatus.Text = message;
            });
        }

        void fixManager_ConnectingStart(object sender, EventArgs e)
        {
            SetLabelStatus(((FixEventArgs)e).Message);
        }

        void fixManager_GettingBullhornListsStart(object sender, EventArgs e)
        {
            SetLabelStatus("Getting Bullhorn Lists ...");
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            objectListView1.ShowGroups = false;
            objectListView1.MultiSelect = false;
            objectListView1.FullRowSelect = true;
            objectListView1.UseHotItem = false;
            objectListView1.UseExplorerTheme = true;

            if (!Directory.Exists(_profileFolder))
            {
                Directory.CreateDirectory(_profileFolder);
            }

            try
            {
                String useFiddlerCore = ConfigurationManager.AppSettings["UseFiddlerCore"];
                String port = ConfigurationManager.AppSettings["Port"];
                if (!String.IsNullOrEmpty(useFiddlerCore) && useFiddlerCore.Trim().ToUpper().Equals("TRUE"))
                {
                    short portNumber = 0;

                    if (!String.IsNullOrEmpty(port) && Int16.TryParse(port, out portNumber))
                    {
                        System.Net.WebRequest.DefaultWebProxy = new System.Net.WebProxy("127.0.0.1", portNumber);
                        Fiddler.FiddlerApplication.Startup(portNumber, false, false);
                    }
                }

            }
            catch (Exception)
            {

                //throw;
            }
        }

        private void objectListView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            var listView = (ObjectListView)sender;
            var selectedObject = (FixInfoObject)listView.SelectedObject;
            var syncInfoDetailObjects = selectedObject.FixInfoDetailObjects;

            DetailsForm detailsForm = new DetailsForm();
            detailsForm.SetListViewObjects(syncInfoDetailObjects);
            detailsForm.ShowDialog();
            
        }

        private void bullhornAccountsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BullhornAccountsForm bullhornAccountsForm = new BullhornAccountsForm();
            bullhornAccountsForm.ShowDialog();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutForm aboutForm = new AboutForm();
            aboutForm.ShowDialog();
        }
    }
}
